package ccm.communicate.smctp;

import ccm.component.override.GridBagConstraints;
import ccm.component.override.JComboBox;
import ccm.component.override.JLabel;
import ccm.component.override.JTextArea;
import ccm.component.override.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import static ccm.common.Utils.speedString;
import static ccm.common.Utils.timeFormatter;

public class SmctpConfigJPanel extends JPanel implements ActionListener
{
    /**
     * 保存被控制
     */
    protected final Smctp smctp;
    /**
     * 通道下拉菜单
     */
    protected final JComboBox<Integer> chanelJComboBox;
    protected final JLabel timeJLabel;
    protected final JLabel waitJLabel;
    protected final JLabel speedInByteJLabel;
    protected final JLabel speedIn8BitJLabel;
    protected final JLabel speedIn10BitJLabel;
    protected final JLabel speedOutByteJLabel;
    protected final JLabel speedOut8BitJLabel;
    protected final JLabel speedOut10BitJLabel;
    protected final JLabel totalHeadCntJLabel;
    protected final JLabel failedHeadCntJLabel;
    protected final JLabel successHeadCntJLabel;
    protected final JTextArea nameIdJLabel;
    protected final JPanel exInfoJPanel;

    SmctpConfigJPanel(Smctp smctpIn) throws NullPointerException
    {
        super();
        if(smctpIn==null){throw new NullPointerException();}
        this.smctp=smctpIn;
        setLayout(new VFlowLayout());
        setBorder(new TitledBorder("SMCTP设置"));

        /*
          通道的面板
         */
        JPanel chanelJComboBoxJPanel=new JPanel();
        add(chanelJComboBoxJPanel);
        chanelJComboBoxJPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        chanelJComboBoxJPanel.add(new JLabel("转发方式"));
        chanelJComboBox=new JComboBox<>(new Integer[]{Smctp.CHANNEL_DEBUG,Smctp.CHANNEL_VISUAL_SCOPE,Smctp.CHANNEL_MAX});
        chanelJComboBox.setSelectedItem(smctp.getDesignatedDataChannel());
        chanelJComboBoxJPanel.add(chanelJComboBox);
        chanelJComboBox.addActionListener(this);
        chanelJComboBox.setRenderer((list,value,index,isSelected,cellHasFocus)->
        {
            JLabel jLabel=new JLabel();
            switch(value)
            {
                case Smctp.CHANNEL_DEBUG:
                    jLabel.setText("转发至调试器");
                    break;
                case Smctp.CHANNEL_VISUAL_SCOPE:
                    jLabel.setText("转发至示波器");
                    break;
                case Smctp.CHANNEL_MAX:
                    jLabel.setText("SMCTP转发");
                    break;
            }
            jLabel.setOpaque(true);
            return jLabel;
        });
        add(nameIdJLabel=new JTextArea());
        exInfoJPanel=new JPanel();
        add(exInfoJPanel);
        exInfoJPanel.setLayout(new GridBagLayout());

        exInfoJPanel.add(timeJLabel=new JLabel(),new GridBagConstraints(0,1,2));
        exInfoJPanel.add(waitJLabel=new JLabel(),new GridBagConstraints(2,1));
        nameIdJLabel.setLineWrap(true);
        nameIdJLabel.setWrapStyleWord(true);
        nameIdJLabel.setEditable(false);
        nameIdJLabel.setBackground(timeJLabel.getBackground());
        nameIdJLabel.setForeground(timeJLabel.getForeground());
        nameIdJLabel.setFont(timeJLabel.getFont());

        exInfoJPanel.add(new JLabel("in"),new GridBagConstraints(1,2,1));
        exInfoJPanel.add(new JLabel("out"),new GridBagConstraints(2,2,1));

        exInfoJPanel.add(new JLabel("Byte: "),new GridBagConstraints(0,3));
        exInfoJPanel.add(speedInByteJLabel=new JLabel(),new GridBagConstraints(1,3));
        exInfoJPanel.add(speedOutByteJLabel=new JLabel(),new GridBagConstraints(2,3));

        exInfoJPanel.add(new JLabel("8b: "),new GridBagConstraints(0,4));
        exInfoJPanel.add(speedIn8BitJLabel=new JLabel(),new GridBagConstraints(1,4));
        exInfoJPanel.add(speedOut8BitJLabel=new JLabel(),new GridBagConstraints(2,4));

        exInfoJPanel.add(new JLabel("10b: "),new GridBagConstraints(0,5));
        exInfoJPanel.add(speedIn10BitJLabel=new JLabel(),new GridBagConstraints(1,5));
        exInfoJPanel.add(speedOut10BitJLabel=new JLabel(),new GridBagConstraints(2,5));

        exInfoJPanel.add(new JLabel("total"),new GridBagConstraints(0,6));
        exInfoJPanel.add(new JLabel("failed"),new GridBagConstraints(1,6));
        exInfoJPanel.add(new JLabel("success"),new GridBagConstraints(2,6));

        exInfoJPanel.add(totalHeadCntJLabel=new JLabel(),new GridBagConstraints(0,7));
        exInfoJPanel.add(failedHeadCntJLabel=new JLabel(),new GridBagConstraints(1,7));
        exInfoJPanel.add(successHeadCntJLabel=new JLabel(),new GridBagConstraints(2,7));

        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(()->
        {
            timeJLabel.setText(timeFormatter(smctp.getLastReceiveUS()));
            String x=smctp.getCurrentConnect();
            if(!Objects.equals(x,nameIdJLabel.getText())){nameIdJLabel.setText(x);}
            final long out=smctp.getOutSpeed();
            final long in=smctp.getInSpeed();
            speedInByteJLabel.setText(speedString(in,false,true));
            speedIn8BitJLabel.setText(speedString(in*8,true,true));
            speedIn10BitJLabel.setText(speedString(in*10,true,true));
            speedOutByteJLabel.setText(speedString(out,false,true));
            speedOut8BitJLabel.setText(speedString(out*8,true,true));
            speedOut10BitJLabel.setText(speedString(out*10,true,true));

            final int success=smctp.getSuccessBytes();
            final int total=smctp.getTotalBytes();
            totalHeadCntJLabel.setText(String.format("%s",speedString(total,false,false)));
            failedHeadCntJLabel.setText(String.format("%s(%.0f%%)",speedString((total-success),false,false),100.0f*(total-success)/(Math.max(total,1))));
            successHeadCntJLabel.setText(String.format("%s(%.0f%%)",speedString((success),false,false),100.0f*success/(Math.max(total,1))));

            {
                StringBuilder stringBuilder=new StringBuilder();
                for(int i=0;i<Smctp.CHANNEL_MAX;++i)
                {
                    if(i!=0){stringBuilder.append(';');}
                    stringBuilder.append(smctp.getWaitLength(i));
                }
                waitJLabel.setText(stringBuilder.toString());
            }
        },0,500,TimeUnit.MILLISECONDS);
    }

    /**
     * 动作事件
     * 处理内部所有面板的触发事件
     */
    public void actionPerformed(ActionEvent e)
    {
        if(e.getSource().equals(chanelJComboBox))
        {
            smctp.setDesignatedDataChannel(getSelectInteger(chanelJComboBox));
        }
    }

    /**
     * 获取下拉菜单选中的整数
     *
     * @param jComboBox 欲获取的下拉菜单
     * @return 整数
     * @throws NullPointerException 获取失败时抛出NullPointerException
     */
    private Integer getSelectInteger(JComboBox<Integer> jComboBox) throws NullPointerException
    {
        Object obj=jComboBox.getSelectedItem();
        if(obj instanceof Integer)
        {return (Integer)obj;}
        throw new NullPointerException();
    }
}
